﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Web;

namespace Job.Core.Common
{
    /// <summary>
    /// 通用上下文，用于统一不同环境下的上下文对象，如 Web/WinForm(无法继承此类)。
    /// </summary>
    public sealed class GenericContext
    {
        #region Properties

        class NameBasedDictionary : Dictionary<string, object> { }

        /// <summary>
        /// 用于 Winform 的线程级下下文容器。
        /// </summary>
        [ThreadStatic]
        private static NameBasedDictionary threadContext;

        /// <summary>
        /// 指示当前是否为一个 Web 应用。
        /// </summary>
        private static readonly bool isWeb = Job.Core.Common.GenericContext.IsWeb();

        /// <summary>
        /// Web 应用程序 Context 保存的键值。
        /// </summary>
        private const string contextKey = "Job.Core.Common.GenericContext";

        /// <summary>
        /// 当前上下文对象。
        /// </summary>
        public static GenericContext Current
        {
            get { return new GenericContext(); }
        }

        #endregion

        #region Constructor

        /// <summary>
        /// 初始化 GenericContext 的实例(禁止外部直接调用)。
        /// </summary>
        private GenericContext()
        {
            if (isWeb)
            {
                if (HttpContext.Current.Items[contextKey] == null)
                    HttpContext.Current.Items[contextKey] = new NameBasedDictionary();
            }
            else
            {
                if (threadContext == null)
                    threadContext = new NameBasedDictionary();
            }
        }

        #endregion

        #region Index

        /// <summary>
        /// 获取或设置指定成员的值。
        /// </summary>
        /// <param name="name">成名名称。</param>
        /// <returns>成员的值。</returns>
        public object this[string name]
        {
            get
            {
                if (string.IsNullOrEmpty(name)) return null;
                NameBasedDictionary cache = GetCache();

                if (cache.Count == 0) return null;

                object result;
                if (cache.TryGetValue(name, out result))
                    return result;
                else
                    return null;
            }
            set
            {
                if (string.IsNullOrEmpty(name)) return;
                NameBasedDictionary cache = GetCache();
                object temp;
                if (cache.TryGetValue(name, out temp))
                    cache[name] = value;
                else
                    cache.Add(name, value);
            }
        }

        #endregion

        #region Methods

        /// <summary>
        /// 获取上下文缓冲对象。
        /// </summary>
        /// <returns></returns>
        private static NameBasedDictionary GetCache()
        {
            return isWeb ? (NameBasedDictionary)HttpContext.Current.Items[contextKey] : threadContext;            
        }

        /// <summary>
        /// 判断当前是否为 Web 应用程序。
        /// </summary>
        /// <returns>是则返回 true，否则返回 false。</returns>
        public static bool IsWeb()
        {
            return AppDomain.CurrentDomain.ShadowCopyFiles && HttpContext.Current != null;
        }

        #endregion
    }
}